package com.rrd.hive.udf;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredObject;
import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.DoubleObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableHiveDecimalObjectInspector;
/**
 * 计算实际摊销本金
 * =IF(G26=0,0,I26-H26*K26)
 * =IF(G27=0,0,I27-H27*K27-SUM(L$26:L26))
 * @author liubaoxin
 *
 */
public class ActualAmortizeAmtUDF extends GenericUDF{
	private WritableHiveDecimalObjectInspector decimalOI;
	private WritableHiveDecimalObjectInspector decimalOI2;
	private WritableHiveDecimalObjectInspector decimalOI3;
	
	private StringObjectInspector stringOI;
	
	@Override
	public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
		// TODO Auto-generated method stub
		if(arguments==null || arguments.length!=4){
			 throw new UDFArgumentTypeException(arguments.length, "输入参数不正确!");
		}
		ObjectInspector loankey=arguments[0];
		ObjectInspector loanAmt=arguments[1];
		ObjectInspector loanRate=arguments[2];
		ObjectInspector dueAmt=arguments[3];
		System.out.println(arguments[1]);
		if(! (loankey instanceof StringObjectInspector)){
			throw new UDFArgumentException("第一个参数进件KEY必须为字符型");
		}
		if(!(loanAmt instanceof  DoubleObjectInspector) && !(loanAmt instanceof  WritableHiveDecimalObjectInspector) ){
			throw new UDFArgumentException("第二个参数每个月还款必须为数字型"+(loanAmt.getClass()));
		}
		if(!(loanAmt instanceof  DoubleObjectInspector) && !(loanRate instanceof  WritableHiveDecimalObjectInspector) ){
			throw new UDFArgumentException("第三个参数利率必须为数字型");
		}
		if(!(dueAmt instanceof  DoubleObjectInspector) && !(loanAmt instanceof  WritableHiveDecimalObjectInspector)){
			throw new UDFArgumentException("第四个参数应还款额必须为数字类型");
		}
		this.stringOI =(StringObjectInspector) loankey;
		this.decimalOI = (WritableHiveDecimalObjectInspector) loanAmt;
		this.decimalOI2 = (WritableHiveDecimalObjectInspector) loanRate;
		this.decimalOI3 = (WritableHiveDecimalObjectInspector) dueAmt;
		
		return ObjectInspectorFactory.getStandardListObjectInspector(
                PrimitiveObjectInspectorFactory.writableHiveDecimalObjectInspector);
	}
	private List<HiveDecimalWritable> list = new ArrayList();
	private String pre_loan_key=null;
	private BigDecimal pre_cost_amt=BigDecimal.valueOf(0);;

	private BigDecimal az_cost_amt=null; //摊余成本
	private BigDecimal counter=BigDecimal.valueOf(0); //摊余成本
	private int c=0;
	@Override
	public Object evaluate(DeferredObject[] arguments) throws HiveException {
		// TODO Auto-generated method stub
		list.clear();
		String loan_key = this.stringOI.getPrimitiveJavaObject(arguments[0].get());
		BigDecimal I_amt=this.decimalOI.getPrimitiveJavaObject(arguments[1].get()).bigDecimalValue();
		BigDecimal H_amt=this.decimalOI2.getPrimitiveJavaObject(arguments[2].get()).bigDecimalValue();
		BigDecimal K_rat=this.decimalOI3.getPrimitiveJavaObject(arguments[3].get()).bigDecimalValue();
		
		counter=counter.add(BigDecimal.valueOf(1));
		c++;
		
		if(this.pre_loan_key==null || this.pre_loan_key.equals("") || !this.pre_loan_key.equals(loan_key)){
			//计算第一期
			
			this.az_cost_amt = I_amt.subtract(H_amt.multiply(K_rat));
			this.pre_cost_amt=this.pre_cost_amt.add(this.az_cost_amt);
			System.out.println("============================K_rat="+K_rat.doubleValue());
			System.out.println("============================I_amt="+I_amt.doubleValue());
			System.out.println("============================H_amt="+H_amt.doubleValue());
			System.out.println("============================"+this.az_cost_amt.doubleValue());
			pre_loan_key=loan_key;
 
		}
		else {
			
			System.out.println("#######################");
			this.az_cost_amt = I_amt.subtract(H_amt.multiply(K_rat)).subtract(this.pre_cost_amt);
			this.pre_cost_amt=this.pre_cost_amt.add(this.az_cost_amt);
			pre_loan_key=loan_key;
		}
		
//		list.add(1, new HiveDecimalWritable(HiveDecimal.create(pre_cost_amt)));
//		list.add(2, new HiveDecimalWritable(HiveDecimal.create(loan_rate)));
		list.add(0, new HiveDecimalWritable(HiveDecimal.create(this.az_cost_amt)));
		list.add(1, new HiveDecimalWritable(HiveDecimal.create(this.pre_cost_amt)));
		list.add(2, new HiveDecimalWritable(HiveDecimal.create(this.counter)));
		return list;
	}

	@Override
	public String getDisplayString(String[] children) {
		// TODO Auto-generated method stub
		return null;
	}

	public static void main(String[] args) {
		BigDecimal I_amt = BigDecimal.valueOf(924);
		I_amt=I_amt.add(BigDecimal.valueOf(100));
		System.out.println(I_amt.doubleValue());
		I_amt=I_amt.add(BigDecimal.valueOf(100));
		System.out.println(I_amt.doubleValue());
		 
		
	}
}
